#ifndef __common_h__
#define __common_h__

#include <float.h>

/* This union helps clarify calling parameters between the PPE and the SPE. */

typedef union
{
	unsigned long long ull;
	unsigned int ui[2];
	void *p;
} addr64;

#define MATRIX_ELEMENT(a, b, c, d) (a)[(b) * (d) + (c)]
#define MATRIX_ROW(a, b, c) (&a[(b) * (c)])
#define MATRIX_ROW_ELEMENT(a, b) a[(b)]

typedef struct
{
	float real;
	float imag;
} complex_float_t; 

typedef float * float_matrix_t;
typedef float * float_matrix_row_t;

typedef complex_float_t * complex_float_matrix_t;
typedef complex_float_t * complex_float_matrix_row_t;


typedef struct arguments
{
	unsigned int lb_i;
	unsigned int ub_i;
	unsigned int lb_j;
	unsigned int ub_j;
	float delta;
	unsigned char padding[4];
} arguments_t;

typedef struct argumentsinit
{
	unsigned long long matrix;
	unsigned int M;
	unsigned int Nexpanded;
	unsigned int R;
	unsigned int NUM_SPE;
} argumentsinit_t;

typedef struct argumentsnorms
{
	unsigned long long output;
	unsigned int startat;
	unsigned char padding[12];
} argumentsnorms_t;

typedef union
{
	argumentsnorms_t normargs;
	argumentsinit_t initargs;
	arguments_t runargs;
} arguments_union_t;

typedef struct norm2reply
{
	float f;
	unsigned char padding[124];
} norm2reply_t;

#define EPSILON FLT_EPSILON
#define NUM_SPE_MAX 16

unsigned int NO_MORE_WORK = 0x0;
unsigned int WORK_CHUNK_READY = 0x1;
unsigned int CALCULATE_NORMS2 = 0x2;

// Macros
//#define sign(n) ((n) < 0.0 ? -1.0 : ((n) > 0.0 ? 1.0 : 0.0) )
#define sign(n) ((n) < 0.0 ? -1.0 : 1.0)
#define min(a,b) ((a) < (b) ? a : b)

#ifdef DEBUG1
#define debug1(...) fprintf(stdout, __VA_ARGS__); fflush(stdout);
#else
#define debug1(...)
#endif

#ifdef DEBUG2
#define debug2(...) fprintf(stdout, __VA_ARGS__); fflush(stdout);
#else
#define debug2(...)
#endif

#ifdef DEBUG3
#define debug3(...) fprintf(stdout, __VA_ARGS__); fflush(stdout);
#else
#define debug3(...)
#endif


#endif /* __common_h__ */
